/**
 * check band width
 * Copyright (c) 2009 cmiscm.com
 * date of final modification : 2009. 07. 15 
*/
package com.cmiscm.net
{
	import com.cmiscm.net.events.NetEvent;
	import com.cmiscm.utils.common.NumberUtilities;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.getTimer;
	
	[Event (name="complete", type="com.cmiscm.events.NetEvent")]
	
	/**
	 * Check Band Width.
     * 
     * @example
     * <listing>
     * package {
	 *    import com.cmiscm.net.AssetsLoader;
     *    import com.cmiscm.net.BandWidth;
     *    import com.cmiscm.net.ImageLoader;
     *    import com.cmiscm.net.XmlLoader;
     *    import com.cmiscm.net.events.NetEvent;
     *    
     *    public class TestLoader
     *    {
     *        private var _bandWidth:BandWidth;
     *        
     *        public function TestLoader()
     *        {
     *            _bandWidth = new BandWidth("http://myhome.com/test.jpg");
     *            _bandWidth.addEventListener(NetEvent.COMPLETE, onComplete);
     *            _bandWidth.start();
     *        }
     *        
     *        private function onComplete(evt:NetEvent):void
     *        {
     *            trace(evt.target.getBandwidth);
     *            
     *            _bandWidth.removeEventListener(NetEvent.COMPLETE, onComplete);
     *            _bandWidth = null;
     *        }
     *    }
     * }
     * </listing>
     * 
     * @see com.cmiscm.net.events.NetEvent NetEvent
     */
	public class BandWidth extends EventDispatcher
	{
		private var _downloadCount:uint = 0;
		private var _downloadTargetCount:uint;
        private var _bandwidthTests:Array = new Array();
        private var _detectedBandwidth:Number;
        private var _startTime:uint;
        private var _testFile:String;        
        private var _loader:URLLoader;
        private var _request:URLRequest;
		
		/**
		 * BandWidth
		 * @param $testFile File URL
		 * @param $count How many times to load
		 * 
		 */		
		public function BandWidth($testFile:String, $count:uint = 3) 
		{
            _downloadTargetCount = $count;
			_testFile = $testFile;
        }
        
        /**
         * Strat 
         * 
         */        
        public function start():void 
        {
        	garbage();
        	_startTime = getTimer();
           	_loader = new URLLoader();
            _request = new URLRequest(_testFile+"?unique="+(new Date()).getTime());
            _loader.load(_request);
            _loader.addEventListener(Event.COMPLETE, onLoad);
        }
        
        /**
         * Get Bandwidth
         * @return 
         * 
         */        
        public function get getBandwidth():Number 
		{
            return _detectedBandwidth;
        }
        
        private function onLoad(evt:Event):void 
        {
            var downloadTime:Number = NumberUtilities.abs(_startTime - getTimer()) / 1000;
            var total:Number = evt.target.bytesTotal;
            var kbps:Number = total * (1 / downloadTime) / 1000;
            _bandwidthTests.push(kbps);

			_downloadCount++;
			
            if(_downloadCount < _downloadTargetCount) start();
            else onComplete();
        }
		
        private function onComplete():void 
        {
            _detectedBandwidth = 0;
            for(var i:uint = 0; i < _bandwidthTests.length; i++) _detectedBandwidth += _bandwidthTests[i];
            _detectedBandwidth /= _downloadCount;
            _detectedBandwidth = int(_detectedBandwidth);
            
            this.dispatchEvent(new NetEvent(NetEvent.COMPLETE));
            
            garbage();
        }
        
        private function garbage():void
        {
        	if (_loader == null) return;
        	else {
				_loader.removeEventListener(NetEvent.COMPLETE, onLoad);
				_loader = null;
				_request = null;
        	}
        }
	}
}